home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / dolmorph / src / morphgo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-19  |  14.2 KB  |  493 lines

  1. /*===========================================
  2.           DolphMorph(ドルフモーフ)
  3.  
  4.       モーフィング&変形アニメ作成ソフト
  5.  
  6.   モーフィングアルゴリズム: EAST 1994
  7.   インターフェース作成:     松内 良介 1994
  8. ===========================================*/
  9. #define    MODULE_MORPHGO
  10. #if 0
  11.     モジュール morphgo.c
  12.  
  13.     モーフィング/変形アニメの設定ダイアログなどの実現部
  14.  
  15.         ●モジュールの初期化・終了
  16.             int        init_morphgo(void);
  17.             void    end_morphgo(void);
  18.  
  19.         ●モーフィング実行用の通信関数
  20.     static    int        morphgo_setupMorph(void);
  21.     static    int        morphgo_succeed(MORPH_INFO *info);
  22.             int        morphgo_getBackImagePixel(int x,int y);
  23.             int        morphgo_getBackFlag(void);
  24.     static    float    morphInterpolateFunc(int type, float a);
  25.  
  26.         ●モーフィング/変形アニメ生成 (デスクトップメニューからの呼び出し)
  27.             int        morphgo_checkExecMorph(int type)
  28.             void    morphgo_execMorph(int type);
  29.  
  30.         ●計算実行中ダイアログ上の部品呼び出し関数
  31.             int        MorphSucceedStopDBtnFunc(idObj, messId, argc, pev, trigger);
  32.         ●設定ダイアログ上の背景画像表示
  33.     static    void    dispBackImage(int idWin);
  34.  
  35.         ●モーフィング/変形アニメ作成の設定ダイアログ上部品の呼び出し関数
  36.             int        MorphSetupBetweenNBoxFunc(idObj)
  37.             int        MorphSetupSpecTIconFunc(idObj)
  38.             int        MorphSetupOkDBtnFunc(void)
  39.             int        MorphSetupCancelDBtnFunc(void)
  40.             int        MorphSetupBackTIconFunc(idObj)
  41.             int        MorphSetupBackWinFunc(idObj, messId)
  42.             int        MorphSetupTransTypeTIconFunc(idObj)
  43. #endif
  44.  
  45. #include <stdio.h>
  46. #include <stdlib.h>
  47. #include <string.h>
  48. #include <winb.h>
  49. #include <te.h>
  50. #include <fntb.h>
  51. #include <gui.h>
  52. #include <egb.h>
  53. #include <wgb.h>
  54. #include <math.h>
  55.  
  56. #include "morph.h"
  57. #include "desktop.h"
  58. #include "morphgo.h"
  59. #include "domorph.h"
  60. #include "wgbmac.h"
  61. #include "guisub.h"
  62. #include "points.h"
  63. #include "image.h"
  64. #include "imstore.h"
  65. #include "alert.h"
  66.  
  67. /*--------------------------------------------------------*/
  68. /*                        部品ID                        */
  69. /*--------------------------------------------------------*/
  70.  
  71.     int    idMorphSucceedWin = -1 ;
  72.     int    idMorphSucceedTitleMsg = -1 ;
  73.     int    idMorphSucceedMsg = -1 ;
  74.     int    idMorphSucceedStopDBtn = -1 ;
  75.     int    idMorphSetupWin = -1 ;
  76.     int    idMorphSetupBetweenNBox = -1 ;
  77.     int    idMorphSetupSpecTIcon[4] = -1 ;
  78.     int    idMorphSetupBackTIcon[2] = -1 ;
  79.     int    idMorphSetupOkDBtn = -1 ;
  80.     int    idMorphSetupCancelDBtn = -1 ;
  81.     int    idMorphSetupTitleMsg = -1 ;
  82.     int    idMorphBetweenMsg = -1 ;
  83.     int    idMorphSetupTransTypeTIcon[4] = -1 ;
  84.  
  85.     int    MorphSetupBetweenNBoxFunc();
  86.  
  87. /*--------------------------------------------------------*/
  88. /*                    モジュール内変数                    */
  89. /*--------------------------------------------------------*/
  90.  
  91.     #define    BACKWID    64
  92.     #define    BACKHT    48
  93.  
  94.     static int morphType;    /* DO_MORPH, DO_TRANSFORM */
  95.     static int nMorphSpec;
  96.     static int nBackFlag;    /* 0:なし  1:あり */
  97.     static float morphSpec[] = { 0.02, 0.05, 0.01, 0.007};
  98.     static int bBreak;        /* 中断フラグ */
  99.     static IMAGE *piBackDisp = NULL;    /* 背景画像 */
  100.     static IMAGE *piBack = NULL;
  101.     static int bBack = 0;
  102.     static int nTransType = 0;    // 変形のぐあい
  103.  
  104. /*--------------------------------------------------------*/
  105. /*                モジュールの初期化/終了                */
  106. /*--------------------------------------------------------*/
  107.  
  108.     int init_morphgo(void)
  109.     {
  110.         RM_initRadioButton(idMorphSetupSpecTIcon,INTNUM(idMorphSetupSpecTIcon),
  111.                            &nMorphSpec);
  112.         RM_initRadioButton(idMorphSetupBackTIcon,INTNUM(idMorphSetupBackTIcon),
  113.                            &nBackFlag);
  114.         RM_initRadioButton(idMorphSetupTransTypeTIcon,
  115.                            INTNUM(idMorphSetupTransTypeTIcon), &nTransType);
  116.         if ((piBackDisp = image_new(BACKWID/2,BACKHT/2)) == NULL)
  117.             return -1;
  118.         bBack = 0;
  119.         return 0;
  120.     }
  121.     
  122.     void end_morphgo(void)
  123.     {
  124.     }
  125.  
  126. /*--------------------------------------------------------*/
  127. /*            モーフィング処理のパラメータ入力            */
  128. /*--------------------------------------------------------*/
  129.  
  130.     static int bExec;
  131.     static int nMorph;
  132.  
  133.     static int morphgo_setupMorph(void)
  134.     {
  135.         bExec = 0;
  136.         RM_moveCenter(idMorphSetupWin);
  137.         MTL_setFlagObj(idDesktopSelectiveHyper, MS_UNSELECT) ;
  138.         MMI_SendMessage(idMorphSetupWin, MM_ATTACH, 1, idDesktopAlertHyper);
  139.         MMI_SendMessage(idMorphSetupWin, MM_SHOW, 0);
  140.         MMI_ExecSystem();
  141.         MMI_SendMessage(idMorphSetupWin, MM_ERASE, 0);
  142.         MMI_SendMessage(idMorphSetupWin, MM_DETACH, 0);
  143.         MTL_resetFlagObj(idDesktopSelectiveHyper, ~MS_UNSELECT) ;
  144.         int var,min,max,delta,ptClm;
  145.         MMI_SendMessage(idMorphSetupBetweenNBox, MM_GETNUMBOX, 5,
  146.                         &var,&min,&max,&delta,&ptClm);
  147.         nMorph = var;
  148.         if (bExec)
  149.             return 0;
  150.         else
  151.             return -1;
  152.     }
  153.  
  154. /*--------------------------------------------------------*/
  155. /*                モーフィング計算中の表示                */
  156. /*--------------------------------------------------------*/
  157.  
  158.     static int morphgo_succeed(MORPH_INFO *info)
  159.     {
  160.         static FRAME frAdjUsr = {2,32+12+16,-2,32+12+16+16+8+20+4+12+3};
  161.         FRAME fr,frWin;
  162.         int cx;
  163.         WINCLIP *pwclp;
  164.         MG_mosDisp(2);
  165.         RM_adjustWinUser(idMorphSucceedWin, &frAdjUsr);
  166.         RM_setClipWinUser(idMorphSucceedWin, &pwclp);
  167.         RM_setOriginZero();
  168.         RM_getWinUserFrame(idMorphSucceedWin, &fr);
  169.         RM_getFrame(idMorphSucceedWin, &frWin);
  170.         WGB_BOXFILL(guiEgbPtr, fr.lupx,fr.lupy,fr.rdwx,fr.rdwy,WINBACK,0);
  171.         cx = (frWin.lupx + frWin.rdwx + 1) / 2;
  172.         char msg[200];
  173.         #define    BARLEN    200
  174.         int len;
  175.         if (info->morphType == DO_MORPH)
  176.             len = (BARLEN/4) * info->varType +
  177.                   _min(BARLEN/4,
  178.                          ((BARLEN/4) * info->moveLimit) / info->moveMax);
  179.         else
  180.             len = (BARLEN/2) * info->varType +
  181.                   _min(BARLEN/2,
  182.                          ((BARLEN/2) * info->moveLimit) / info->moveMax);
  183.         WGB_RBOXFILL(guiEgbPtr,cx-100,frWin.lupy+32+12+16+16+8-20,
  184.                      BARLEN, 20, WHITE,0);
  185.         WGB_RBOXFILL(guiEgbPtr,cx-100,frWin.lupy+32+12+16+16+8-20,
  186.                      len,20, BLACK,0);
  187.         sprintf(msg,"   pass %d  %d / %d   ",
  188.                 info->varType+1, info->moveMax, info->moveLimit);
  189.         RM_putstring12(guiEgbPtr,
  190.                        cx-(6/2)*strlen(msg), frWin.lupy+32+12+16+16+8+20+4-20,
  191.                        msg,BLACK,0);
  192.         RM_resetClipWinUser(pwclp);
  193.         RM_recoverOrigin();
  194.         MG_mosDisp(3);
  195.  
  196.         EVENT *pev;
  197.         MMI_iosense();
  198.         if (MMI_GetEvnt(EVALL, &pev) == NOERR)
  199.             MMI_ExecEvnt(pev);
  200.  
  201.         return (bBreak ? -1 : 0);
  202.     }
  203.  
  204. /*--------------------------------------------------------*/
  205. /*              外部のための背景画像アクセス              */
  206. /*--------------------------------------------------------*/
  207.  
  208.     // ★このへんのモジュール分割はめちゃくちゃ。要再考
  209.  
  210.     int morphgo_getBackImagePixel(int x,int y)
  211.     {
  212.         if (bBack == 0 || nBackFlag == 0)
  213.             return 0x7fff;
  214.         if (x < 0 || piBack->width <= x || y < 0 || piBack->height <= y)
  215.             return 0x7fff;
  216.         return (int)((unsigned short *)(piBack->image))
  217.                 [piBack->width * y + x];
  218.     }
  219.  
  220.     int morphgo_getBackFlag(void)
  221.     {
  222.         if (bBack == 0 || nBackFlag == 0)
  223.             return 0;
  224.         else
  225.             return 1;
  226.     }
  227.  
  228. /*--------------------------------------------------------*/
  229. /*               モーフィングの速度変化関数               */
  230. /*--------------------------------------------------------*/
  231.  
  232.     static float morphInterpolateFunc(int type, float a)
  233.     // a: 0~1
  234.     // type : 0=直線的  1=だんだん速く  2=だんだん遅く
  235.     //          3=最初遅く、まんなか速く、最後遅く
  236.     {
  237.         switch (type)
  238.         {
  239.         case 0:
  240.             return a;
  241.         case 1:
  242.             return a*a;
  243.         case 2:
  244.             return sqrt(a);
  245.         case 3:
  246.             if (a <= 0.5)
  247.                  return a * a * 2.0;
  248.             else
  249.                 return 0.5 + sqrt((a - 0.5)/2.0);
  250.         default:
  251.             return a;
  252.         }
  253.     }
  254.  
  255. /*--------------------------------------------------------*/
  256. /*                   モーフィング実行!                   */
  257. /*--------------------------------------------------------*/
  258.  
  259.     int    morphgo_checkExecMorph(int type)
  260.     {
  261.         if (points_checkMorphImages() != 0)
  262.             return -1;
  263.         else
  264.             return 0;
  265.     }
  266.  
  267.     void morphgo_execMorph(int type)
  268.                     // type 0=モーフィング  1=変形アニメ
  269.     {
  270.         int moscsr;
  271.         static char alertTitle[30] = "モーフィング/変形アニメ作成";
  272.         LIST *plPOINT,*plLINE;
  273.         int imwid,imht;    // 画像のサイズ
  274.         morphType = (type == 1 ? DO_TRANSFORM : DO_MORPH);
  275.         int err;
  276.         if ((err = points_checkMorphImages()) != 0)
  277.         {
  278.             if (err == POINTS_IMAGE_NO_THERE)
  279.                 dispAlertMessage(alertTitle, "操作点設定ウィンドウのA,B側に"
  280.                                  "画像が存在しないので、モーフィング"
  281.                                  "(変形アニメ作成)できません");
  282.             else if (err == POINTS_IMAGE_MISMATCH_SIZE)
  283.                 dispAlertMessage(alertTitle, "操作点設定ウィンドウのA,B側の"
  284.                                  "画像の大きさが違うので、モーフィング"
  285.                                  "(変形アニメ作成)できません");
  286.             goto END;
  287.         }
  288.         points_getImageSize(&imwid, &imht);
  289.         if (morphType == DO_MORPH)
  290.         {
  291.           MMI_SendMessage(idMorphSetupTitleMsg, MM_SETMSG, 1, "モーフィング");
  292.           MMI_SendMessage(idMorphSucceedTitleMsg, MM_SETMSG, 1,
  293.                             "モーフィング計算実行中");
  294.           strcpy(alertTitle, "モーフィング");
  295.         }
  296.         else
  297.         {
  298.           MMI_SendMessage(idMorphSetupTitleMsg, MM_SETMSG, 1,"変形アニメ作成");
  299.           MMI_SendMessage(idMorphSucceedTitleMsg, MM_SETMSG, 1,
  300.                             "変形アニメ 計算実行中");
  301.           strcpy(alertTitle, "変形アニメ作成");
  302.         }
  303.         MorphSetupBetweenNBoxFunc(idMorphSetupBetweenNBox);
  304.       /* 背景画像の登録 */
  305.         IMAGE *pi;
  306.         pi = imstore_getImage(imstore_getMarkNum(0));
  307.         bBack = 0;
  308.         if (pi != NULL)
  309.         {
  310.             if (piBack != NULL)
  311.                 image_delete(piBack);
  312.             piBack = NULL;
  313.             if ((piBack = image_copy(pi)) == NULL)
  314.             {
  315.                 alert_noMemory(alertTitle);
  316.                 goto END;
  317.             }
  318.             image_zoomdown(piBackDisp, piBack);
  319.             bBack = 1;
  320.         }
  321.       /* 各種パラメータの入力 */
  322.         if (morphgo_setupMorph() != 0)
  323.             goto END;
  324.         plPOINT = list_new(sizeof(MORPH_POINT));
  325.         plLINE  = list_new(sizeof(MORPH_LINE));    // ★ちゃんと作成できた?
  326.         if (points_makeMorphPoints(plPOINT, plLINE) != 0)
  327.             goto AFTER_MORPHTERM;
  328.       /* モーフィング開始 */
  329.         MG_mosDisp(2);
  330.         MG_PushPtr(MOSICON_WAIT, &moscsr);
  331.         MG_mosDisp(3);
  332.         RM_moveCenter(idMorphSucceedWin);
  333.         MMI_SendMessage(idMorphSucceedWin, MM_ATTACH, 1, idDesktopAlertHyper);
  334.         MMI_SendMessage(idMorphSucceedWin, MM_SHOW, 0);
  335.         morphInitialize(imwid,imht,morphSpec[nMorphSpec],plPOINT,plLINE);
  336.       /* 中間画像を生成 */
  337.         int i;
  338.         bBreak = 0;
  339.         for (i=1; i<=nMorph; i++)
  340.         {
  341.             IMAGE *pi;
  342.             if ((pi = image_new(imwid,imht)) == NULL)
  343.             {
  344.                 alert_noMemory(alertTitle);
  345.                 break;
  346.             }
  347.             static char msgbuf[80];
  348.             sprintf(msgbuf, "  %d枚中 %d枚目を計算しています  ",nMorph,i);
  349.             MMI_SendMessage(idMorphSucceedMsg, MM_SETMSG, 1, msgbuf);
  350.             MMI_SendMessage(idMorphSucceedMsg, MM_SHOW, 0);
  351.             float t;
  352.             t = (float)(i-1) / (float)(nMorph-1);
  353.             t = morphInterpolateFunc(nTransType, t);
  354.             if (morphExec(t, morphgo_succeed, 1, morphType) != 0)
  355.             {
  356.                 dispAlertMessage(alertTitle,"計算を中断しました");
  357.                 break;
  358.             }
  359.             int x,y;
  360.             for (y=0; y<imht; y++)
  361.                 for (x=0; x<imwid; x++)
  362.                 {
  363.                     int r,g,b;
  364.                     morphGetColor(x,y,&r,&g,&b);
  365.                     ((unsigned short*)pi->image)[imwid*y+x] = g*1024+r*32+b;
  366.                 }
  367.             if (imstore_storeNewImage(1,pi,-1) < 0)
  368.             {
  369.                 alert_noMemory(alertTitle);
  370.                 break;
  371.             }
  372.         }
  373.       /* モーフィング終了 */
  374.       MORPHTERM:;
  375.         morphTerminate();
  376.         MMI_SendMessage(idMorphSucceedWin, MM_ERASE, 0);
  377.         MMI_SendMessage(idMorphSucceedWin, MM_DETACH, 0);
  378.         MG_mosDisp(2);
  379.         MG_PopPtr(moscsr);
  380.         MG_mosDisp(3);
  381.       AFTER_MORPHTERM:;
  382.         list_destroy(plPOINT);
  383.         list_destroy(plLINE);
  384.       END:;
  385.     }
  386.  
  387. /*--------------------------------------------------------*/
  388. /*             設定ダイアログ上の背景画像表示             */
  389. /*--------------------------------------------------------*/
  390.  
  391.     static void dispBackImage(int idWin)
  392.     {
  393.         RM_setOriginZero();
  394.         WINCLIP *pClip;
  395.         RM_setClipWinUser(idWin, &pClip);
  396.         FRAME fr;
  397.         RM_getWinUserFrame(idWin,&fr);
  398.         if (!bBack)
  399.         {
  400.             WGB_BOXFILL(guiEgbPtr,fr.lupx,fr.lupy,fr.rdwx,fr.rdwy,
  401.                         WINBACK,0);
  402.             WGB_BOXLINE(guiEgbPtr,fr.lupx,fr.lupy,fr.rdwx,fr.rdwy,
  403.                         BLACK,0);
  404.             RM_putstring12(guiEgbPtr, (fr.lupx+fr.rdwx)/2 - (12*3)/2,
  405.                            (fr.lupy+fr.rdwy)/2 - 12/2, "未設定", BLACK, 0);
  406.         }
  407.         else
  408.             image_disp(piBackDisp, fr.lupx, fr.lupy, BACKWID,BACKHT);
  409.         RM_resetClipWinUser(pClip);
  410.         RM_recoverOrigin();
  411.     }
  412.  
  413. /*--------------------------------------------------------*/
  414. /*                   部品の呼び出し関数                   */
  415. /*--------------------------------------------------------*/
  416.  
  417.                                     /* idMorphSucceedStopDBtn:MJ_DBUTTONL40 */
  418.     int    MorphSucceedStopDBtnFunc(void)
  419.     {
  420.         bBreak = 1;
  421.         return NOERR ;
  422.     }
  423.                                     /* idMorphSetupBetweenNBox:MJ_NUMBOXL40 */
  424.     int    MorphSetupBetweenNBoxFunc(int idObj)
  425.     {
  426.         int var,min,max,delta,ptClm;
  427.         MMI_SendMessage(idObj,MM_GETNUMBOX,5, &var,&min,&max,&delta,&ptClm);
  428.         static char msg[40];
  429.         if (morphType == DO_MORPH)
  430.             sprintf(msg, "(%d枚を補間) ", var-2);
  431.         else /* morphType == DO_TRANSFORM */
  432.             sprintf(msg, "(%d枚を生成) ", var-1);
  433.         MMI_SendMessage(idMorphBetweenMsg, MM_SETMSG, 1, msg);
  434.         MMI_SendMessage(idMorphBetweenMsg, MM_SHOW, 0);
  435.         return NOERR ;
  436.     }
  437.                         /* idMorphSetupSpecTIcon[0],[1],[2],[3]:MJ_TICONL40 */
  438.     int    MorphSetupSpecTIconFunc(int idObj)
  439.     {
  440.         RM_pushRadioButton(idObj,idMorphSetupWin,
  441.                            idMorphSetupSpecTIcon,INTNUM(idMorphSetupSpecTIcon),
  442.                            &nMorphSpec);
  443.         return NOERR ;
  444.     }
  445.                                         /* idMorphSetupOkDBtn:MJ_DBUTTONL40 */
  446.     int    MorphSetupOkDBtnFunc(void)
  447.     {
  448.         bExec = 1;
  449.         MMI_SetHaltFlag(TRUE);
  450.         return NOERR ;
  451.     }
  452.                                     /* idMorphSetupCancelDBtn:MJ_DBUTTONL40 */
  453.     int    MorphSetupCancelDBtnFunc(void)
  454.     {
  455.         bExec = 0;
  456.         MMI_SetHaltFlag(TRUE);
  457.         return NOERR ;
  458.     }
  459.                                 /* idMorphSetupBackTIcon[0],[1]:MJ_TICONL40 */
  460.     int    MorphSetupBackTIconFunc(int idObj)
  461.     {
  462.         RM_pushRadioButton(idObj,idMorphSetupWin,
  463.                            idMorphSetupBackTIcon,INTNUM(idMorphSetupBackTIcon),
  464.                            &nBackFlag);
  465.         return NOERR ;
  466.     }
  467.  
  468.                                             /* idMorphSetupWin:MJ_WINDOWL40 */
  469.     int    MorphSetupBackWinFunc(int idObj, int messId)
  470.     {
  471.         if (messId == MM_SHOW)
  472.         {
  473.             RM_roundFramePosition(idObj, 2,2);
  474.             dispBackImage(idObj);
  475.         }
  476.         else if (messId == MM_MOVE)
  477.         {
  478.             RM_roundFramePosition(idObj, 2,2);
  479.             dispBackImage(idObj);
  480.         }    
  481.         return NOERR ;
  482.     }
  483.                    /* idMorphSetupTransTypeTIcon[0],[1],[2],[3]:MJ_TICONL40 */
  484.     int    MorphSetupTransTypeTIconFunc(int idObj)
  485.     {
  486.         RM_pushRadioButton(idObj,idMorphSetupWin,
  487.                            idMorphSetupTransTypeTIcon,
  488.                            INTNUM(idMorphSetupTransTypeTIcon),
  489.                            &nTransType);
  490.         return NOERR ;
  491.     }
  492.  
  493.